#pragma once

MS_ALIGN(16) class Plane : public Vector3
{
public:
	// Variables.
	float W;

	// Constructors.
	__forceinline Plane() {}
	__forceinline Plane(const Plane& p) : Vector3(p),	W(p.W) {}
	__forceinline Plane(const Vector4& v) : Vector3(v.X, v.Y, v.Z), W(v.W) {}
	__forceinline Plane(float x, float y, float z, float w) : Vector3(x, y, z),	W(w) {}
	__forceinline Plane(Vector3 n, float w) : Vector3(n), W(w) {}

	// Functions.
	__forceinline float PlaneDot(const Vector3& p) const { return X*p.X + Y*p.Y + Z*p.Z - W; }
	Plane Flip() const { return Plane(-X, -Y, -Z, -W); }

	bool operator==( const Plane& v ) const { return X == v.X && Y == v.Y && Z == v.Z && W == v.W; }
	bool operator!=( const Plane& v ) const { return X != v.X || Y != v.Y || Z != v.Z || W != v.W; }

	__forceinline float operator|( const Plane& v ) const { return X*v.X + Y*v.Y + Z*v.Z + W*v.W; }
	Plane operator+( const Plane& v ) const { return Plane( X + v.X, Y + v.Y, Z + v.Z, W + v.W ); }
	Plane operator-( const Plane& v ) const { return Plane( X - v.X, Y - v.Y, Z - v.Z, W - v.W ); }
	Plane operator/( float Scale ) const { const float RScale = 1.f/Scale; return Plane( X * RScale, Y * RScale, Z * RScale, W * RScale ); }
	Plane operator*( float Scale ) const { return Plane( X * Scale, Y * Scale, Z * Scale, W * Scale ); }
	Plane operator*( const Plane& v ) { return Plane ( X*v.X,Y*v.Y,Z*v.Z,W*v.W ); }
	Plane operator+=( const Plane& v ) { X += v.X; Y += v.Y; Z += v.Z; W += v.W; return *this; }
	Plane operator-=( const Plane& v ) { X -= v.X; Y -= v.Y; Z -= v.Z; W -= v.W; return *this; }
	Plane operator*=( float Scale ) { X *= Scale; Y *= Scale; Z *= Scale; W *= Scale; return *this; }
	Plane operator*=( const Plane& v ) { X *= v.X; Y *= v.Y; Z *= v.Z; W *= v.W; return *this; }
	Plane operator/=( float v ) { const float RV = 1.f/v; X *= RV; Y *= RV; Z *= RV; W *= RV; return *this; }

	void Normalize()
	{
	}

}  GCC_ALIGN(16);
